"use strict";

/**新式的人性化数据检测函数，实现人性化数据检测*/
function DataTypeDetect() {
    let currentInstance = this;

    /**数据的检测结果*/
    let getDetectValue;

    /**数据检测器*/
    function detectApplet(data, dictInstance) {
        let FinalDetectValue;
        if (Object.prototype.toString.call(dictInstance) === '[object Object]') {
            let tempData = Object.prototype.toString.call(data).split(' ');
            tempData = tempData[1].substr(0, tempData[1].length - 1);
            if (dictInstance.EnableDict) {
                if (dictInstance.deepLink) {
                    switch (dictInstance.RetValueType) {
                        case 0:
                            if (dictInstance.Bind[tempData] === undefined) {
                                FinalDetectValue = tempData;
                            } else {
                                FinalDetectValue = dictInstance.Bind[tempData].aliasVal;
                            }
                            break;
                        case 1:
                            if (dictInstance.Bind[tempData] === undefined) {
                                FinalDetectValue = tempData;
                            } else {
                                FinalDetectValue = dictInstance.Bind[tempData].aliasDsc;
                            }
                            break;
                        case 2:
                            if (dictInstance.Bind[tempData] === undefined) {
                                FinalDetectValue = tempData;
                            } else {
                                FinalDetectValue = [dictInstance.Bind[tempData].aliasVal, dictInstance.Bind[tempData].aliasDsc];
                            }
                            break;
                        default:
                            FinalDetectValue = Object.prototype.toString.call(data);
                            break;
                    }
                } else {
                    FinalDetectValue = tempData;
                }
            } else {
                FinalDetectValue = Object.prototype.toString.call(data);
            }
        } else {
            FinalDetectValue = Object.prototype.toString.call(data);
        }
        return FinalDetectValue;
    }

    /**词条数据检测器*/
    function dictEntryChk(EntryObj) {
        let FinalDictEntry = true;
        try {
            for (let EntryDetect in EntryObj) {
                let corrNum = 0;
                for (let subDictEntry in EntryObj[EntryDetect]) {
                    switch (subDictEntry.toLowerCase()) {
                        case "aliasval":
                            corrNum++;
                            break;
                        case "aliasdsc":
                            corrNum++;
                            break;
                    }
                }
                if (corrNum !== 2) {
                    throw new Error("词条不完整！");
                }
            }
        } catch (e) {
            FinalDictEntry = false;
        }
        return FinalDictEntry;
    }

    /**词典合法检测*/
    function dictDetect(DictObject) {
        let FinalDetectValue = true;
        try {
            if (currentInstance.emptyObjectDetect(DictObject)) {
                FinalDetectValue = false
            } else {
                for (let chkDict in DictObject) {
                    switch (chkDict.toLowerCase()) {
                        case "enabledict":
                            if (detectApplet(DictObject[chkDict]) !== '[object Boolean]') {
                                throw new Error("EnableDict属性不是布尔值！");
                            }
                            break;
                        case "retvaluetype":
                            if (detectApplet(DictObject[chkDict]) === '[object Number]') {
                                if (DictObject[chkDict] > 2 || DictObject[chkDict] < 0) {
                                    throw new Error("RetValueType属性的值仅能为数字，且不能大于2或不能小于0！");
                                }
                            }
                            break;
                        case "bind":
                            if (
                                detectApplet(DictObject[chkDict]) !== '[object Object]'
                                &&
                                currentInstance.emptyObjectDetect(DictObject[chkDict]) !== false
                            ) {
                                throw new Error("词库没有数据！");
                            }
                            break;
                        default:
                            throw new Error("词典数据出现未知的属性！");
                    }
                }
            }
        } catch (e) {
            FinalDetectValue = false;
        }
        return FinalDetectValue;
    }

    /**数据检测选择器*/
    function dataDetectSwitch(dataSources) {
        if (detectApplet(currentInstance._GlobalOperate) === '[object Object]') {
            getDetectValue = detectApplet(dataSources, currentInstance._GlobalOperate);
        } else {
            getDetectValue = detectApplet(dataSources);
        }
    }

    /**词典导入器*/
    function dictImport(Sources) {
        let FinalChangeObj;
        if (currentInstance.emptyObjectDetect(Sources) === false) {
            FinalChangeObj = {};
            for (let impAttr in Sources) {
                switch (impAttr.toLowerCase()) {
                    case "enabledict":
                        FinalChangeObj.EnableDict = currentInstance.lightCopy(Sources[impAttr]);
                        break;
                    case "bind":
                        if (dictEntryChk(Sources[impAttr])) {
                            FinalChangeObj.deepLink = true;
                            FinalChangeObj.Bind = currentInstance.lightCopy(Sources[impAttr]);
                        } else {
                            FinalChangeObj.deepLink = false;
                            FinalChangeObj.Bind = {}
                        }
                        break;
                    case "retvaluetype":
                        FinalChangeObj.RetValueType = currentInstance.lightCopy(Sources[impAttr]);
                        break;
                }
            }
        }
        return FinalChangeObj;
    }

    /**新的词典数据*/
    let GlobalOperate = {}

    switch (arguments.length) {
        case 0:
            getDetectValue = undefined;
            break;
        case 1:
            if (detectApplet(arguments[0]) === '[object Object]') {
                /**获取名为“_GlobalOperate”属性的配置数据对象，不区分大小写*/
                let _GlobalOperate;
                for (let getGlobalOperate in arguments[0]) {
                    switch (getGlobalOperate.toLowerCase()) {
                        case "_globaloperate":
                            _GlobalOperate = arguments[0][getGlobalOperate];
                            break;
                    }
                }
                /**获取名为“_GlobalOperate”属性的配置数据对象，不区分大小写*/

                /**检查是否获取到配置数据*/
                if (detectApplet(_GlobalOperate) === "[object Object]") {
                    /**检测传递过来的词典*/
                    if (dictDetect(_GlobalOperate)) {
                        let dictChk;
                        for (let getDictEntry in _GlobalOperate) {
                            switch (getDictEntry.toLowerCase()) {
                                case 'bind':
                                    dictChk = currentInstance.lightCopy(_GlobalOperate[getDictEntry]);
                                    break;
                            }
                        }
                        /**导入数据并纠正*/
                        GlobalOperate = dictImport(_GlobalOperate);
                        this._GlobalOperate = currentInstance.lightCopy(GlobalOperate);
                    } else {
                        dataDetectSwitch(arguments[0]);
                    }
                } else {
                    dataDetectSwitch(arguments[0]);
                }
            } else {
                dataDetectSwitch(arguments[0]);
            }
            break;
        default:
            if (dictDetect(arguments[arguments.length - 1])) {
                GlobalOperate = dictImport(arguments[arguments.length - 1]);
                getDetectValue = [];
                if (GlobalOperate === undefined) {
                    for (let num = 0; num < arguments.length; num++) {
                        if (Object.prototype.toString.call(currentInstance._GlobalOperate) === "[object Object]") {
                            if (currentInstance._GlobalOperate.EnableDict) {
                                getDetectValue[num] = detectApplet(arguments[num], currentInstance._GlobalOperate);
                            } else {
                                getDetectValue[num] = Object.prototype.toString.call(arguments[num]);
                            }
                        } else {
                            getDetectValue[num] = Object.prototype.toString.call(arguments[num]);
                        }
                    }
                } else {
                    for (let num = 0; num < arguments.length; num++) {
                        if (num >= (arguments.length - 1)) {
                            break;
                        }
                        getDetectValue[num] = detectApplet(arguments[num], GlobalOperate);
                    }
                }
            } else {
                getDetectValue = [];
                for (let num = 0; num < arguments.length; num++) {
                    if (Object.prototype.toString.call(currentInstance._GlobalOperate) === "[object Object]") {
                        if (currentInstance._GlobalOperate.EnableDict) {
                            getDetectValue[num] = detectApplet(arguments[num], currentInstance._GlobalOperate);
                        } else {
                            getDetectValue[num] = Object.prototype.toString.call(arguments[num]);
                        }
                    } else {
                        getDetectValue[num] = Object.prototype.toString.call(arguments[num]);
                    }
                }
            }
            break;
    }

    return getDetectValue;
}

module.exports = DataTypeDetect;